package com.whitlock.backend.exception.handler;

import com.whitlock.backend.exception.BusinessServiceException;
import com.whitlock.backend.exception.FtpConnectException;
import com.whitlock.backend.exception.Http4xxException;
import com.whitlock.backend.exception.RestException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthenticatedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import java.io.IOException;

@RestControllerAdvice
public class RestExceptionHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(RestExceptionHandler.class);

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<RestException> handleMethodArgumentNotValidException(MethodArgumentNotValidException exception) {
        LOGGER.error("exception:", exception);
        return new ResponseEntity<>(new RestException("400", exception.getBindingResult().getAllErrors().get(0).getDefaultMessage()), HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(BusinessServiceException.class)
    public ResponseEntity<RestException> handleBusinessServiceException(BusinessServiceException exception) {
        LOGGER.error("exception:", exception);
        return new ResponseEntity<>(new RestException("500", exception.getErrorMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(FtpConnectException.class)
    public ResponseEntity<RestException> handleFtpConnectException(FtpConnectException exception) {
        LOGGER.error("exception:", exception);
        return new ResponseEntity<>(new RestException("408", exception.getErrorMessage()), HttpStatus.REQUEST_TIMEOUT);
    }


    @ExceptionHandler(Http4xxException.class)
    public ResponseEntity<RestException> handleHttp4xxException(Http4xxException exception) {
        LOGGER.error("exception:", exception);
        return new ResponseEntity<>(new RestException(String.valueOf(exception.getErrorCode()), exception.getErrorMessage()), HttpStatus.valueOf(exception.getErrorCode()));
    }

    @ExceptionHandler(UnauthenticatedException.class)
    public ResponseEntity<RestException> handleUnauthenticatedException(UnauthenticatedException exception) {
        LOGGER.error("exception:", exception);
        return new ResponseEntity<>(new RestException("401", "用户未登录"), HttpStatus.UNAUTHORIZED);
    }

    @ExceptionHandler(HttpMessageNotReadableException.class)
    public ResponseEntity<RestException> handleHttpMessageNotReadableException(HttpMessageNotReadableException exception) {
        LOGGER.error("exception:", exception);
        return new ResponseEntity<>(new RestException("400", "无效请求"), HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<RestException> handleIllegalArgumentException(IllegalArgumentException exception) {
        LOGGER.error("exception:", exception);
        return new ResponseEntity<>(new RestException("400", exception.getMessage()), HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(AuthenticationException.class)
    public ResponseEntity<RestException> handleAuthenticationException(AuthenticationException exception) {
        LOGGER.error("exception:", exception);
        return new ResponseEntity<>(new RestException("401", "Token无效"), HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<RestException> handleException(Exception exception) {
        LOGGER.error("exception:", exception);
        return new ResponseEntity<>(new RestException("500", "系统异常，请稍后再尝试"), HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(IOException.class)
    public ResponseEntity<RestException> handleIOException(IOException exception) {
        LOGGER.error("exception:", exception);
        return new ResponseEntity<>(new RestException("500", "文件下载异常"), HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(AuthorizationException.class)
    public ResponseEntity<RestException> handleException(AuthorizationException exception) {
        LOGGER.error("exception:", exception);
        return new ResponseEntity<>(new RestException("403", "权限不足"), HttpStatus.FORBIDDEN);
    }

    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public ResponseEntity<RestException> handleException(MaxUploadSizeExceededException exception) {
        LOGGER.error("exception:", exception);
        return new ResponseEntity<>(new RestException("400", "上传文件大小超出限制,最大为100M"), HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
